//
//  Ast.h
//  LightBasic
//
//  Created by Albert on 25/03/2011.
//  Copyright 2011 LightBasic Development Team. All rights reserved.
//
#pragma once
#include "Token.h"

namespace lbc {

    // forward declare
    class Type;

    // Ast nodes
    struct Ast;
    struct AstStatement;
    struct AstExpression;
    struct AstDeclaration;
    #define AST_CLASS(klass) struct klass;
    #include "AstClasses.def.h"


    /**
     * pure abstract class for ast visitors
     */
    struct AstVisitor : boost::noncopyable {
        /// implement Visit methods
        #define AST_CLASS(klass) virtual void Visit(klass * ast) { if (debug) { std::cout << __PRETTY_FUNCTION__ << std::endl; } }
        #include "AstClasses.def.h"
        
        /// create
        AstVisitor(bool debug = false) : debug(debug) {}
        
        /// is visitor in debug mode?
        bool debug;
    };
    
    
    /// Visibility specifiers
    enum Visibility
    {
        VisPublic,
        VisProtected,
        VisPrivate
    };
    

    /**
     * Base class for AST noted
     */
    struct Ast : boost::noncopyable {
        /// for visitor pattern
        virtual void Accept(AstVisitor *) = 0;
        
        /// virtual desctructor
        virtual ~Ast() {}
    };
    
    
    /// Declare ast node that can be allocated and visited by the visitor
    #define DECLARE_AST() \
        virtual void Accept(AstVisitor * visitor) { visitor->Visit(this); } \
        void * operator new(size_t); \
        void operator delete(void *);
    #include "AstExpr.inc.h"
    #include "AstStmt.inc.h"
    #include "AstGeneric.inc.h"

    // remove accpet
    #undef DECLARE_AST
}
